import {
  WechatyBuilder,
  ScanStatus,
  Message,
  Contact,
} from '../src/mods/mod.js' // from 'wechaty'
import { Configuration, OpenAIApi } from "openai"

import qrTerm from 'qrcode-terminal'

const configuration = new Configuration({
  apiKey: "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",
})
const openai = new OpenAIApi(configuration)
const options = {
  name: 'ding-dong-bot',
}

const bot = WechatyBuilder.build(options)

bot
  .on('logout', onLogout)
  .on('login', onLogin)
  .on('scan', onScan)
  .on('error', onError)
  .on('message', onMessage)
  .start()
  .catch(async e => {
    console.error('Bot start() fail:', e)
    await bot.stop()
    process.exit(-1)
  })

function onScan(qrcode: string, status: ScanStatus) {
  if (status === ScanStatus.Waiting || status === ScanStatus.Timeout) {
    qrTerm.generate(qrcode)

    const qrcodeImageUrl = [
      'https://wechaty.js.org/qrcode/',
      encodeURIComponent(qrcode),
    ].join('')

    console.info('onScan: %s(%s) - %s', ScanStatus[status], status, qrcodeImageUrl)
  } else {
    console.info('onScan: %s(%s)', ScanStatus[status], status)
  }
}

function onLogin(user: Contact) {
}

function onLogout(user: Contact) {
}

function onError(e: Error) {
  console.error('Bot error:', e)
}

const friendMap: any = {}

async function onMessage(msg: Message) {
  const room = msg.room()
  if (room) {
    return
  }

  const friend = msg.talker()?.name()
  let question = msg.text()
  if (question === '开始') {
    friendMap[friend]= {
      talkList: [],
      status: 'start'
    }
    msg.say('好的, 你可以问新问题了')
    return
  }
  if (question === '退出') {
    friendMap[friend] = {
      talkList: [],
      status: 'stop'
    }
    msg.say('好的, 我已经关闭')
    return
  }
  if (msg.self()) {
    return
  }
  const whiteList = ['梦！', '回忆', '妈', '空空']
  if (whiteList.indexOf(friend) > -1 && friendMap[friend] && friendMap[friend].status === 'start') {
    const talkList = friendMap[friend].talkList
    let answer: any = ''
    try {
      answer = await chat(talkList?.join(' ') + question)
      talkList?.push(question + '\n' + answer + '\n')
      msg.say(answer)
    } catch (err: any) {
      friendMap[friend].talkList = []
      msg.say(err)
    }
  }
}

function chat(question: string) {
  let answer = ''
  return new Promise(async (resolve, reject) => {
    try {
      const res = await openai.createCompletion({
        model: "text-davinci-003",
        prompt: question,
        temperature: 0.9,
        max_tokens: 4097,
        top_p: 1,
        frequency_penalty: 0.0,
        presence_penalty: 0.6,
        stream: true
      }, { responseType: 'stream' })
      res.data.on('data', (data: any) => {
        const lines = data.toString().split('\n').filter((line: any) => line.trim() !== '')
        for (const line of lines) {
          const message = line.replace(/^data: /, '')
          if (message === '[DONE]') {
            resolve(answer)
            return
          }
          try {
            const parsed = JSON.parse(message)
            answer += parsed.choices[0].text
          } catch (error) {
            console.error('Could not JSON parse stream message', message, error)
          }
        }
      })
    } catch {
      reject('我们说的太多了, 还是换个话题吧')
    }
  })
}
